﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using CSequence;
using Ini;
using Microsoft.VisualBasic.PowerPacks;
using System.Xml;
using System.Xml.XPath;
using System.Data.Common;

namespace Sequence
{
    public partial class FrmSequence2 : Form
    {
        string m_sPath;
        string m_sId;
        FileSequence oFileSequence = null;       
        bool bSCbConnected = false;
        public enum eSourceControlState { CheckedIn, CheckedOutByMe, CheckedOutNotByMe, Unknown };
        eSourceControlState eSCState = eSourceControlState.Unknown;
        private string sIniFilePath = "C:\\Sapiens\\Sequence\\Sequence.ini";
        Point MouseDownLocation;
        long iRunNum = 0;
        public IniFile oIni = null;
        private bool m_bShowLines = true;
        Control m_oConContextMenuStripSourceControl = null;
        class LineConnection
        {
            public CStep oFrom;
            public CStep oTo;
            public LineShape dynamicLine;
            public int iControlIndex;
            public string sFromConnect;
            public string sToConnect;
        }

        private List<LineConnection> arrLineConnections = new List<LineConnection>();

        public void SourceControl(string sCon)
        {
            if (GetWiki() != null)
            {
                bSCbConnected = true;
                sourceControlToolStripMenuItem.Enabled = true;
            }
            else
            {
                bSCbConnected = false;
                sourceControlToolStripMenuItem.Enabled = false;

            }
        }

        public void OpenByName(string sName)
        {
            WriteMessage("Opening " + sName, "OpenByName");
            string sTempId = "";
            String sSql = @"
select * 
from t_api_qd_process 
where 
  t_api_qd_process.name='$Name$'
";
            sSql = sSql.Replace("$Name$", sName);
            sSql = CSqlString.TestType(sSql, GetConnectionType());
            try
            {
                DbCommand command = GetConnection().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;
                DbDataReader oDataReader = command.ExecuteReader();

                if (oDataReader.Read())
                {
                    sTempId = oDataReader["ID"].ToString();
                }
                oDataReader.Close();
                oDataReader.Dispose();
                command.Dispose();
            }
            catch (Exception ex)
            {
                WriteMessage(ex.ToString(), "OpenByName");               
            }
           
            // Load the metadata 
            if (sTempId != "")
                sId = sTempId;
        }


        private void WriteMessage(string sMess, String sIn)
        {
            rtbErrors.Text = sMess + "\r\n" + rtbErrors.Text;
            rtbErrors.Refresh();
        }

        public string sId
        {
            get
            {
                return m_sId;
            }
            set
            {
                m_sId = value;
                tstbId.Text = m_sId;
                if (m_sId.Length > 0)
                {
                    UpdateIcon();
                    m_oConContextMenuStripSourceControl = panel1; 
                    if (oFileSequence == null)
                        oFileSequence = new FileSequence();

                    String sSql = "select t_api_qd_process.name as process, t_api_qd_process_step.ID,t_api_qd_process_step.PROCESS_ID,";
                    sSql += "  t_api_qd_process_step.NAME,t_api_qd_process_step.QUERY_NAME,t_api_qd_process_step.STEP_MODE, ";
                    sSql += "  t_api_qd_process_step.TYPE as sType ";
                    sSql += "from t_api_qd_process ";
                    sSql += "  left outer join t_api_qd_process_step on  t_api_qd_process.id =  t_api_qd_process_step.process_id ";
                    sSql += "where t_api_qd_process.id = " + m_sId + " ";
                    sSql += "order by t_api_qd_process_step.ID";
                    sSql = CSqlString.TestType(sSql, GetConnectionType());

                    try
                    {
                        DbCommand command = GetConnection().CreateCommand();
                        command.CommandText = sSql;
                        command.CommandType = CommandType.Text;
                        DbDataReader oDataReader = command.ExecuteReader();

                        while (oDataReader.Read())
                        {
                            tstbName.Text = oDataReader["PROCESS"].ToString();
                            if (oDataReader["ID"].ToString().Length > 0)
                            {
                                
                                CStep oCurrStep = oFileSequence.oSteps.Find(element => element.sId == oDataReader["ID"].ToString());
                                if (oCurrStep == null)
                                {                               
                                    CStep oStep = new CStep(oDataReader, GetConnection(), oFileSequence);
                                    AddParams(oStep);
                                    oFileSequence.oSteps.Add(oStep);
                                    AddControl(oStep);
                                }                                
                            }
                        }
                        oDataReader.Close();
                        oDataReader.Dispose();
                        command.Dispose();
                        oFileSequence.sName = tstbName.Text;                        
                    }
                    catch (Exception ex)
                    {
                        DialogResult dialogResult = MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }      
             
                    AddLines();
                    UpdateLines();
                    oFileSequence.bIsDirty = false;
                }
            }
        }

        private void AddParams(CStep oStep)
        {
            String sSql = @"
select id, name, PARAMS_VALUE, params_type 
from t_api_qd_process_step_params 
where process_id=$ProcessId$ and STEP_ID=$Id$
order by t_api_qd_process_step_params.id";

            sSql  = sSql.Replace("$ProcessId$", oStep.sProcessId);
            sSql = sSql.Replace("$Id$", oStep.sId);
            sSql = CSqlString.TestType(sSql, GetConnectionType());
            try
            {
                DbCommand command = GetConnection().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;
                DbDataReader oDataReader = command.ExecuteReader();

                while (oDataReader.Read())
                {
                    string sID = oDataReader[0].ToString();
                    string sInName = oDataReader[1].ToString();
                    string sInValue = oDataReader[2].ToString();
                    string sParamsType = oDataReader[3].ToString();
                    switch (sParamsType)
                    {
                        case "I":
                            if (sInName != null)
                            {
                                CInput oIn = new CInput(sInName, sInValue, sID, oStep);
                                oStep.lInputs.Add(oIn);
                            }
                            break;
                        case "O":
                            if (sInName != null)
                            {
                                COutput oOut = new COutput(sInName, sInValue, sID, oStep);
                                oStep.lOutputs.Add(oOut);
                            }
                            break;
                        case "D":
                            if (sInName != null)
                            {
                                CDisplay oDis = new CDisplay(sInName, sInValue, sID, oStep);
                                oStep.lDisplay.Add(oDis);
                            }
                            break;
                    }

                }
                oDataReader.Close();
                oDataReader.Dispose();
                command.Dispose();

            }
            catch (Exception ex)
            {
                DialogResult dialogResult = MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


        private void AddLines()
        {
            List<string> lKeys = new List<string>();
            int i = 0;
            foreach (CStep oSt in oFileSequence.oSteps)
            {
                foreach (CInput oIn in oSt.lInputs)
                {
                    string[] sInputs = oIn.sValue.Split('>');
                    if (sInputs.Count() == 2)
                    {
                        CStep oStTo = oFileSequence.oSteps.Find(element => element.sName == sInputs[0]);
                        if (oStTo != null)
                        {
                            // Now we need to find the Output Param for the oStTo step
                            COutput oOut = oStTo.lOutputs.Find(element => element.sName == sInputs[1]);

                            if (oOut != null)
                            {
                                int iX1 = GetX1(oSt), iX2 = GetX2(oStTo);
                                int iY1 = GetY1(oSt, sInputs[1]), iY2 = GetY2(oStTo, sInputs[1]);

                                string sControlName = "LineConnection_" + oSt.sId + "." + oIn.sID + "-" + oStTo.sId + "." + oOut.sID;
                                Control[] oCon = panel1.Controls.Find( sControlName, false);
                                LineShape dynamicLine = null;

                                if (oCon.Count() > 0)
                                {
                                   //oCon[0].X1 = iX1; oCon[0].X2 = iX2;
                                   // oCon[0].Y1 = iY1; oCon[0].Y2 = iY2;
                                }
                                else
                                {

                                    dynamicLine = new LineShape();
                                    ShapeContainer sc = new ShapeContainer();
                                    dynamicLine.Parent = sc;
                                    dynamicLine.X1 = iX1; dynamicLine.X2 = iX2;
                                    dynamicLine.Y1 = iY1; dynamicLine.Y2 = iY2;

                                    LineConnection oLineConnections = new LineConnection();
                                    oLineConnections.oFrom = oSt;
                                    oLineConnections.oTo = oStTo;
                                    oLineConnections.dynamicLine = dynamicLine;
                                    oLineConnections.sFromConnect = oIn.sName;
                                    oLineConnections.sToConnect = oOut.sName;
                                    sc.Name = "LineConnection_" + oSt.sId + "." + oIn.sID + "-" + oStTo.sId + "." + oOut.sID;
                                    arrLineConnections.Add(oLineConnections);

                                    dynamicLine.Visible = true;
                                    panel1.Controls.Add(sc);
                                    oLineConnections.iControlIndex = i;
                                }                                
                                i++;
                            }

                        }
                    }
                }
            }
            Console.WriteLine("Number of lines = " + i.ToString() + " of " + panel1.Controls.Count.ToString() + " Controls");
        }

        private void AddControls()
        {
            panel1.Controls.Clear();
            foreach (CStep oSt in oFileSequence.oSteps)
            {
                //if (oSt.iControlIndex == -1)
                //{
                    AddControl(oSt);
                //}                
            }
        }

        private void AddControl(CStep oSt)
        {
            if (oSt.sType == "TextComment")
            {
                TextBox dynamicTextBox = null;
                Control[] oCon = panel1.Controls.Find("txtComment" + oSt.sId,  false);
                if (oCon.Count() > 0)
                    dynamicTextBox = (TextBox)oCon[0];
                else
                {
                    dynamicTextBox = new TextBox();
                    dynamicTextBox.Name = "txtComment" + oSt.sId;                    
                    dynamicTextBox.Tag = oSt.sId;
                    dynamicTextBox.AutoSize = false;
                    dynamicTextBox.Multiline = true;
                    panel1.Controls.Add(dynamicTextBox);
                    dynamicTextBox.ContextMenuStrip = contextMenuStrip1;
                    CInput oInput = oSt.lInputs.Find(element => element.sName == "Text");
                    if (oInput != null)
                        dynamicTextBox.Text = oInput.sValue;
                    
                }
                dynamicTextBox.TextChanged += new EventHandler(  usStep_TextChanged);
                dynamicTextBox.MouseMove += new MouseEventHandler(usStep_MouseMove);
                dynamicTextBox.MouseUp += new MouseEventHandler(usStep_MouseUp);
                dynamicTextBox.MouseDown += new MouseEventHandler(usStep_MouseDown);
                dynamicTextBox.Left = Convert.ToInt32(oSt.GetDisplayValue("X", "15")); dynamicTextBox.Top = Convert.ToInt32(oSt.GetDisplayValue("Y", "15"));
                dynamicTextBox.Width = Convert.ToInt32(oSt.GetDisplayValue("Width", "200")); dynamicTextBox.Height = Convert.ToInt32(oSt.GetDisplayValue("Height", "200"));
                dynamicTextBox.Visible = true;
            }
            else
            {
                usStep dynamicStep = null;
                Control[] oCon = panel1.Controls.Find(oSt.GetControlName(), false);
                if (oCon.Count() > 0)
                    dynamicStep = (usStep)oCon[0];
                else
                {
                    dynamicStep = new usStep(oSt, contextMenuStrip1);
                    dynamicStep.Name = "usStep" + oSt.sId;
                    dynamicStep.Tag = oSt.sId;
                    panel1.Controls.Add(dynamicStep);                    
                }
                dynamicStep.MouseMove += new MouseEventHandler(usStep_MouseMove);
                dynamicStep.MouseUp += new MouseEventHandler(usStep_MouseUp);
                dynamicStep.MouseDown += new MouseEventHandler(usStep_MouseDown);
                dynamicStep.Left = Convert.ToInt32(oSt.GetDisplayValue("X", "15")); dynamicStep.Top = Convert.ToInt32(oSt.GetDisplayValue("Y", "15"));
                dynamicStep.Width = Convert.ToInt32(oSt.GetDisplayValue("Width", "200")); dynamicStep.Height = Convert.ToInt32(oSt.GetDisplayValue("Height", "200"));
                dynamicStep.Visible = true;
            }
        }

        private void usStep_TextChanged(object sender, EventArgs e)
        {
            if (sender.GetType().ToString() == "System.Windows.Forms.TextBox")
            {
                TextBox oStepTextBox = (TextBox)sender;
                string sId = oStepTextBox.Tag.ToString();
                CStep oStep = oFileSequence.oSteps.Find(element => element.sId == sId);
                if (oStep != null)
                {
                    oStep.SetInputValue("Text", oStepTextBox.Text);
                }
            }
        }

        private void usStep_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (sender.GetType().ToString() == "System.Windows.Forms.TextBox")
                {
                    TextBox oStep = (TextBox)sender;
                    oStep.Left = e.X + oStep.Left - MouseDownLocation.X;
                    oStep.Top = e.Y + oStep.Top - MouseDownLocation.Y;
                }
                else
                {
                    usStep oStep = (usStep)sender;
                    oStep.Left = e.X + oStep.Left - MouseDownLocation.X;
                    oStep.Top = e.Y + oStep.Top - MouseDownLocation.Y;
                }
            }
        }

        private void usStep_MouseUp(object sender, MouseEventArgs e)
        {
            if (sender.GetType().ToString() == "System.Windows.Forms.TextBox")
            {
                TextBox oUsStep = (TextBox)sender;
                string sId = oUsStep.Tag.ToString();
                CStep oStep = oFileSequence.oSteps.Find(element => element.sId == sId);

                if (oStep != null)
                {
                    oUsStep.Top = ((int)(oUsStep.Top / 5) * 5);
                    oUsStep.Left = ((int)(oUsStep.Left / 5) * 5);                    

                    oStep.SetDisplayValue("Y", oUsStep.Top.ToString());
                    oStep.SetDisplayValue("X", oUsStep.Left.ToString());
                }                                
            }
            else
            {
                usStep oUsStep = (usStep)sender;
                CStep oStep = oFileSequence.FindStep(oUsStep.Text);

                if (oStep != null)
                {
                    oUsStep.Top = ((int)(oUsStep.Top / 5) * 5);
                    oUsStep.Left = ((int)(oUsStep.Left / 5) * 5);

                    oStep.SetDisplayValue("Y", oUsStep.Top.ToString());
                    oStep.SetDisplayValue("X", oUsStep.Left.ToString());
                }
                UpdateLines();
                Text = oFileSequence.GetProcessName();
            }
        }

        private void usStep_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                MouseDownLocation = e.Location;
            }
        }


        private void UpdateLines()
        {
            foreach (LineConnection oLineConn in arrLineConnections)
            {
                CStep oFrom = oFileSequence.oSteps.Find(element => element.sId == oLineConn.oFrom.sId);
                CStep oTo = oFileSequence.oSteps.Find(element => element.sId == oLineConn.oTo.sId);
                
                //chech the step has net been deleted 
                if ((oFrom != null) && (oTo != null))
                {
                    int iX1 = GetX1(oFrom), iX2 = GetX2(oTo);
                    int iY1 = GetY1(oFrom, oLineConn.sFromConnect), iY2 = GetY2(oTo, oLineConn.sToConnect);

                    oLineConn.dynamicLine.X1 = iX1; oLineConn.dynamicLine.X2 = iX2;
                    oLineConn.dynamicLine.Y1 = iY1; oLineConn.dynamicLine.Y2 = iY2;
                    oLineConn.dynamicLine.Visible = m_bShowLines;
                }
            }
        }

        private int GetY1(CStep oSt, string sName)
        {    
            string sname = oSt.GetControlName();
            return Convert.ToInt16(oSt.GetDisplayValue("Y")) + ((usStep)(panel1.Controls[oSt.GetControlName()])).GetInputOffset(sName);
        }

        private int GetY2(CStep oSt, string sName)
        {
            int iRet = 0;
            try { iRet = Convert.ToInt16(oSt.GetDisplayValue("Y")) + ((usStep)(panel1.Controls[oSt.GetControlName()])).GetOutputOffset(sName); }
            catch (Exception Ex) { }
            return iRet;
        }


        private int GetX1(CStep oSt)
        {
            return Convert.ToInt16(oSt.GetDisplayValue("X"));
        }

        private int GetX2(CStep oSt)
        {
            return Convert.ToInt16(oSt.GetDisplayValue("X")) + (Convert.ToInt16(oSt.GetDisplayValue("Width")));
        }

        public FrmSequence2()
        {
            InitializeComponent();
            oIni = new IniFile(sIniFilePath);
        }

        public void SetParam(string sParm)
        {
            // example batchId=51 
            WriteMessage("Set Param - " + sParm, "SetParam");
            string[] arrParams = sParm.Split('=');
            if (arrParams.Length == 2)
            {
                foreach (CStep oSt in oFileSequence.oSteps)
                {
                    foreach (CInput oIn in oSt.lInputs)
                    {
                        if ((oIn.sName == arrParams[0]) && (oIn.sValue == "?"))
                        {
                            oIn.sValue = arrParams[1];
                        }
                    }
                }
            }
        }

        public DbConnection GetConnection()
        {
            return ((Sequence.MDISequence)(this.MdiParent)).GetConnection();
        }

        public string GetConnectionType()
        {
            return ((Sequence.MDISequence)(this.MdiParent)).GetConnectionType();
        }

        public CWikiSourceControl GetWiki()
        {
            return ((Sequence.MDISequence)(this.MdiParent)).GetWiki();
        }

        private void FrmSequence_Load(object sender, EventArgs e)
        {
            this.Text = "Sequence -" + m_sPath;
        }

        private void UpdateIcon()
        {
            if (bSCbConnected)
            {
                CWikiSourceControl oWikiSourceControl = GetWiki();
                CWikiSourceControl.CSCStatus oCSCStatus = oWikiSourceControl.FindById(tstbId.Text);

                if (oCSCStatus != null)
                {
                    string sUser = oIni.IniReadValue("Wiki", "User", "");
                    if (oCSCStatus.sCheckedOutTo == sUser)
                    {
                        //The process is checked out by me 
                        this.Icon = Properties.Resources.IconCheckedOutTo;
                        eSCState = eSourceControlState.CheckedOutByMe;
                        checkInToolStripMenuItem.Enabled = true;
                        checkOutToolStripMenuItem.Enabled = !checkInToolStripMenuItem.Enabled;

                    }
                    else if ((oCSCStatus.sCheckedOutTo != "-") && (oCSCStatus.sCheckedOutTo != ""))
                    {
                        // The Process must be checked out to someone else
                        this.Icon = Properties.Resources.IconCheckedOutNotMe;
                        eSCState = eSourceControlState.CheckedOutNotByMe;
                        checkInToolStripMenuItem.Enabled = false;
                        checkOutToolStripMenuItem.Enabled = false;
                    }
                    else
                    {
                        // The Process must is not checked out 
                        this.Icon = Properties.Resources.Sequence;
                        eSCState = eSourceControlState.CheckedIn;
                        checkInToolStripMenuItem.Enabled = false;
                        checkOutToolStripMenuItem.Enabled = !checkInToolStripMenuItem.Enabled;
                    }
                }
                else
                {
                    this.Icon = Properties.Resources.Sequence;
                    eSCState = eSourceControlState.Unknown;
                }
            }
        }

        public void SetCommentLocation(TextBox oTextBox, CStep oSt)
        {
            oTextBox.Width = (int)(Convert.ToDouble(oSt.GetDisplayValue("Width", "100")));
            oTextBox.Height = (int)(Convert.ToDouble(oSt.GetDisplayValue("Height", "100")));
            //oTextBox.Height = this.Height - 10;
            oTextBox.Top = (int)(Convert.ToDouble(oSt.GetDisplayValue("Y", "15")));
            oTextBox.Left = (int)(Convert.ToDouble(oSt.GetDisplayValue("X", "15")));
        }

        private void upToolStripMenuItem_Click(object sender, EventArgs e)
        {

            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep"))
                ChangeStepDisplay(sFocusName, "Y", -5);
            else
                ChangeTextBoxDisplay(sFocusName, "Y", -5);
        }

        private void downToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep"))
                ChangeStepDisplay(sFocusName, "Y", 5);
            else
                ChangeTextBoxDisplay(sFocusName, "Y", 5);
        }

        private void rightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep"))
                ChangeStepDisplay(sFocusName, "X", 5);
            else
                ChangeTextBoxDisplay(sFocusName, "X", 5);
        }

        private void leftToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep"))
                ChangeStepDisplay(sFocusName, "X", -5);
            else
                ChangeTextBoxDisplay(sFocusName, "X", -5);
        }

        private void incHeightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep"))
                ChangeStepDisplay(sFocusName, "Height", 5);
            else
                ChangeTextBoxDisplay(sFocusName, "Height", 5);
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void ChangeTextBoxDisplay(string sFocusName, string sDisplay, int iVal)
        {
            if (sFocusName != "")
            {
                TextBox oTextBox = (TextBox)panel1.Controls[sFocusName];
                string sId = oTextBox.Tag.ToString();
                CStep oSt = oFileSequence.oSteps.Find(element => element.sId == sId);
                if (oSt != null)
                {
                    oSt.SetDisplayValue(sDisplay, (Convert.ToDouble(oSt.GetDisplayValue(sDisplay, "100")) + iVal).ToString());
                    SetCommentLocation(oTextBox, oSt);
                }
            }
        }

        private void ChangeStepDisplay(string sFocusName, string sDisplay, int iVal)
        {
            if (sFocusName != "")
            {
                usStep oUcStep = (usStep)panel1.Controls[sFocusName];
                string sId = oUcStep.Tag.ToString();
                CStep oSt = oFileSequence.oSteps.Find(element => element.sId == sId);
                if (oSt != null)
                {
                    oSt.SetDisplayValue(sDisplay, (Convert.ToDouble(oSt.GetDisplayValue(sDisplay, "0")) + iVal).ToString());
                    oUcStep.SetLocation();
                    UpdateLines();
                    oUcStep.Refresh();
                    Text = oFileSequence.GetProcessName();
                }
            }
        }

        private string GetFocusName()
        {
            string sRet = "";
            foreach ( Control oCon in panel1.Controls)
            {
                if ( oCon.Name.Contains("usStep") )
                {
                    if (((usStep)oCon).bHasFocus)
                    {
                        sRet = oCon.Name;
                        break;
                    }
                }
                else if (oCon.Focused)
                {
                    sRet = oCon.Name;
                    break;
                }
            }
            return sRet;
        }

        private void decHeightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep") )
                ChangeStepDisplay(sFocusName, "Height", -5);         
            else if (sFocusName.Contains("txtComment") )
                ChangeTextBoxDisplay(sFocusName, "Height", -5);         
        }

        private void incWidthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep"))
                ChangeStepDisplay(sFocusName, "Width", 5);  
            else if (sFocusName.Contains("txtComment") )
                ChangeTextBoxDisplay(sFocusName, "Width", 5); 
        }

        private void decWidthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sFocusName = GetFocusName();
            if (sFocusName.Contains("usStep"))
                ChangeStepDisplay(sFocusName, "Width", -5); 
            else if (sFocusName.Contains("txtComment"))
                ChangeTextBoxDisplay(sFocusName, "Width", -5);
        }

        private void cboSteps_SelectedIndexChanged(object sender, EventArgs e){}
        private void cmdRun_Click(object sender, EventArgs e){}
        private void button1_Click(object sender, EventArgs e){}
        private void button2_Click(object sender, EventArgs e){}
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { }
        private void textBox1_KeyDown(object sender, KeyEventArgs e) { }
        private void textBox1_KeyUp(object sender, KeyEventArgs e) { }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            ShowProperties();
        }

        private void ShowProperties()
        {
            CheckToSave();
            FrmProperties oFrmProperties = new FrmProperties();
            oFrmProperties.m_connection = GetConnection();

            CStep oStep = FindFocusStep();
            if (oStep != null)
            {
                oFrmProperties.LoadData(oStep);
                oFrmProperties.ShowDialog(this);
                if (oFrmProperties.bToSave)
                {
                    oStep = oFrmProperties.m_oStep;
                    ((usStep)panel1.Controls[oStep.GetControlName()]).Display(oStep, contextMenuStrip1);
                    oFileSequence.bIsDirty = true;
                    Text = oFileSequence.GetProcessName();
                }
            }
        }
        private void CheckToSave()
        {
            
            /*if (oFileSequence.bIsDirty)
            {
                if (MessageBox.Show("Save changes first", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    Save();
                }
            }*/
            Save();
        }

        private CStep FindFocusStep()
        {
            CStep oStep = null;
            foreach (Control oCon in panel1.Controls)
            {
                if (oCon.GetType() == typeof(usStep))
                {
                    if (((usStep)oCon).bHasFocus)
                    {
                        oStep = oFileSequence.FindStep(oCon.Text);
                    }
                }
            }
            return oStep;
        }

        public void RunSequence()
        {
            CLog oLog = new CLog(oIni, rtbErrors);        
            CheckToSave();
            Cursor.Current = Cursors.WaitCursor;
            ClearCalValue();


            oFileSequence.bIfElseFlag = false;

            // Get all the inputs ( ? ) 
            List<string> arrInputs = new List<string>();
            foreach (CStep oSt in oFileSequence.oSteps)
            {
                foreach (CInput oIn in oSt.lInputs)
                {
                    if (oIn.sValue == "?")
                        arrInputs.Add(oSt.sName + "." + oIn.sName);
                }
            }

            // Get any user inputs 
            GetInputs(arrInputs);

            if (oFileSequence.oSteps.Count > 0)
            {

                // Now run each step on order
                oFileSequence.iCurrentStep = 1;
                bool bFinished = false;
                while (!bFinished)
                {
                    if (oFileSequence.iCurrentStep <= oFileSequence.oSteps.Count())
                    {
                        CStep oSt = oFileSequence.oSteps.Find(element => element.sId == oFileSequence.iCurrentStep.ToString());
                        if (oSt != null)
                        {
                            string sControlName = oSt.GetControlName();
                            if (sControlName.Contains("usStep"))
                            {
                                
                                if (ToRunStep(oSt))
                                {
                                    oLog.StartStep(oSt); string sDebug = "";
                                    HighlightCurrentStep(oSt, sControlName);
                                    bFinished = oSt.Calculate(oLog.InFileName(), oLog.OutFileName(), ref sDebug);
                                    HighlightCurrentStep(oSt, sControlName);                                    
                                    oLog.EndStep(oSt, sDebug);
                                }
                                else
                                {
                                    oLog.WriteMessage("    Step '" + oSt.sName + "' skipped due to if step");
                                }
                            }
                        }
                        oFileSequence.iCurrentStep++;
                        Application.DoEvents();
                    }
                    else
                    {
                        this.Text = "Finished...";
                        bFinished = true;
                    }

                    // allow the user to cancel the run - when running the ToolTipText
                    // is set to Cancel
                    if (toolStripButton2.ToolTipText == "Run")
                        bFinished = true;
                }

                


                oLog.Finish(oFileSequence);
                Cursor.Current = Cursors.Default;
            }
            toolStripButton2.ToolTipText = "Run";
        }

        private void HighlightCurrentStep(CStep oSt,string sControlName)
        {
            Control oCon = panel1.Controls[sControlName];
            ActiveControl = oCon;                             
            Text = "Step (" + oSt.sId + ") " + oSt.sName;
            
            if (((usStep)oCon).ShowType == usStep.eShowType.Values)
                ((usStep)oCon).ShowType = usStep.eShowType.Values;
            Application.DoEvents();
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            if (toolStripButton2.ToolTipText == "Run") 
            {
                toolStripButton2.ToolTipText = "Cancel";
                RunSequence();  
            }
            else
            {
                toolStripButton2.ToolTipText = "Run";
                Application.DoEvents();
            }
        }

        private bool ToRunStep(CStep oStep)
        {
            bool bRet = true;

            if (oFileSequence.bIfElseFlag != false)
            {
                if ((oStep.sType != "IF") && (oStep.sType != "ELSE") && (oStep.sType != "END IF"))
                    bRet = false;
            }
            return bRet;
        }

        private void GetInputs(List<string> arrInputs)
        {
            if (arrInputs.Count() > 0)
            {
                FrmGetValues oFrmGetValues = new FrmGetValues(arrInputs);
                //oFrmGetValues.Parent = this;
                oFrmGetValues.ShowDialog();
                if (oFrmGetValues.arrResults != null)
                {

                    foreach (string sVal in oFrmGetValues.arrResults)
                    {
                        string[] arrRes = sVal.Split('\t');
                        if (arrRes.Count() == 2)
                        {
                            string[] arrStepName = arrRes[0].Split('.');
                            if (arrStepName.Count() == 2)
                            {
                                CStep oStep = oFileSequence.oSteps.Find(element => element.sName == arrStepName[0]);
                                if (oStep != null)
                                {
                                    CInput oInput = oStep.lInputs.Find(element => element.sName == arrStepName[1]);
                                    if (oInput != null)
                                        oInput.sCalValue = arrRes[1];
                                }
                            }
                        }
                    }
                }
            }
        }



        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void cboScale_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            ClearCalValue();
            Invalidate();
        }

        private void ClearCalValue()
        {
            foreach (CStep oStep in oFileSequence.oSteps)
            {
                oStep.bCalculated = false;
                oStep.m_bFirstTimeInFor = true;
                foreach (COutput oOut in oStep.lOutputs)
                    oOut.sCalValue = "";
                foreach (CInput oIn in oStep.lInputs)
                    oIn.sCalValue = "";
            }
            oFileSequence.iForCount = 0;
            oFileSequence.sLastError = "";
            oFileSequence.bIfElseFlag = false;

        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            if (toolStripButton4.ToolTipText == "Show Name")
            {
                toolStripButton4.ToolTipText = "Show Values";
                toolStripButton4.Image = Properties.Resources.Properties;
                foreach (Control oCon in panel1.Controls)
                {
                    if (oCon.GetType() == typeof(usStep))
                        ((usStep)oCon).ShowType = usStep.eShowType.Values;
                }
            }
            else
            {
                toolStripButton4.ToolTipText = "Show Name";
                toolStripButton4.Image = Properties.Resources.Values;
                foreach (Control oCon in panel1.Controls)
                {
                    if (oCon.GetType() == typeof(usStep))
                        ((usStep)oCon).ShowType = usStep.eShowType.Names;
                }
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            ProcessStartInfo pi = new ProcessStartInfo(tstbPath.Text);
            //pi.Arguments = Path.GetFileName(tbWorkingFolder.Text);
            pi.UseShellExecute = true;
            pi.WorkingDirectory = tstbPath.Text;
            pi.FileName = tstbPath.Text;
            pi.Verb = "OPEN";

            try
            {
                Process.Start(pi);
            }
            catch (Exception ex)
            {
                WriteMessage(ex.Message + " (" + tstbPath.Text + ")", "toolStripButton5_Click");
            }
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {            
            CheckToSave();
            Cursor.Current = Cursors.WaitCursor;
            panel1.Controls.Clear();
            oFileSequence.oSteps.Clear();
            RefreshScreen();
            Cursor.Current = Cursors.Default;
        }

        private void RefreshScreen()
        {
            //Path = tstbPath.Text;
            sId = tstbId.Text;
            Text = oFileSequence.GetProcessName();
            panel1.Refresh();
        }

        private void RunSql(String sSql)
        {
            try
            {
                sSql = CSqlString.TestType(sSql, GetConnectionType());
                DbCommand command = GetConnection().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;
                int iRows = command.ExecuteNonQuery();
                command.Dispose();
            }
            catch (Exception ex)
            {
                WriteMessage(ex.Message + " (" + sSql + ")", "RunSql"); 
            }
        }

        public string GetTypeNumber(string sType)
        {
            string sRet = "";
            switch (sType)
            {
                case "Constants":
                    sRet = "0";
                    break;
                case "QueryDef":
                    sRet = "1";
                    break;
                case "QueryDefUpdate":
                    sRet = "2";
                    break;
                case "UpdateQueryDef":
                    sRet = "2";
                    break;
                case "UpdateAlisWebService":
                    sRet = "3";
                    break;
                case "AlisWebService":
                    sRet = "4";
                    break;
                case "IF":
                    sRet = "5";
                    break;
                case "ELSE":
                    sRet = "6";
                    break;
                case "END IF":
                    sRet = "7";
                    break;
                case "FOR":
                    sRet = "8";
                    break;
                case "END FOR":
                    sRet = "9";
                    break;
                case "QueryDefProcess":
                    sRet = "10";
                    break;
                case "FOR LIST":
                    sRet = "11";
                    break;
                case "END FOR LIST":
                    sRet = "12";
                    break;
                case "Calculation":
                    sRet = "13";
                    break;
                case "ChildUpdateQueryDef":
                    sRet = "14";
                    break;
                case "TextComment":
                    sRet = "15";
                    break;
                case "Input":
                    sRet = "16";
                    break;
                case "Output":
                    sRet = "17";
                    break;
                case "Map":
                    sRet = "18";
                    break;
                default:
                    Debug.Assert(false);
                    break;
            }
            return sRet;
        }

        private void NewStep(int iTop, int iLeft, string sName, string sType)
        {
            CheckToSave();
            string sTypeNumer = GetTypeNumber(sType);

            iTop = (iTop / 5) * 5;
            iLeft = (iLeft / 5) * 5;

            string sSql = "Begin\r\nInsert into T_API_QD_PROCESS_STEP (PROCESS_ID,ID,NAME,TYPE,QUERY_NAME, STEP_MODE ) values (" + sId + ",(select Nvl(max(ID),0)+1 from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),'" + sName + "'," + sTypeNumer + ",'" + sName + "','None');\r\n";
            sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAMS_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),1,'D','X','" + iLeft.ToString() + "');\r\n";
            sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAMS_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),2,'D','Y','" + (iTop + 30).ToString() + "');\r\n";
            sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAMS_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),3,'D','Height','110');\r\n";            
            sSql += "insert into  T_API_QD_PROCESS_STEP_PARAMS (PROCESS_ID,STEP_ID,ID,PARAMS_TYPE, NAME, PARAMS_VALUE ) values (" + sId + ",(select Nvl(max(ID),0) from T_API_QD_PROCESS_STEP where PROCESS_ID=" + sId + "),4,'D','Width','200');\r\nEnd;";

            RunSql(sSql);            
            RefreshScreen();
        }

        private void tsbNew_Click(object sender, EventArgs e)
        {
            //NewStep();
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
            Save();
        }


        public string GetSaveCommand()
        {

            string sRet = "delete from T_API_QD_PROCESS where ID=" + tstbId.Text + ";\r\n";
            sRet += "delete from T_API_QD_PROCESS_STEP where PROCESS_ID=" + tstbId.Text + ";\r\n";
            sRet += "delete from T_API_QD_PROCESS_STEP_PARAMS where PROCESS_ID=" + tstbId.Text + ";\r\n";
            sRet += "insert into T_API_QD_PROCESS (ID,NAME) values(" + tstbId.Text + ",'" + tstbName.Text + "' );\r\n";

            foreach (CStep oStep in oFileSequence.oSteps)
                sRet += oStep.ToSql();

            return sRet;
        }

        public void Save()
        {
            Cursor.Current = Cursors.WaitCursor;
            if (tstbId.Text == "")
            {
                string sSql = "insert into T_API_QD_PROCESS (ID,NAME) values((select Nvl(max(ID),0)+1 from T_API_QD_PROCESS), '" + tstbName.Text + "' )";
                sSql = CSqlString.TestType(sSql, GetConnectionType());
                RunSql(sSql);
            }
            else
            {
                string sSql = "Update T_API_QD_PROCESS set NAME='" + tstbName.Text + "' where ID=" + tstbId.Text;
                sSql = CSqlString.TestType(sSql, GetConnectionType());
                RunSql(sSql);
            }

            foreach (CStep oStep in oFileSequence.oSteps)
            {
                oStep.sErrorMessage = "";
                oStep.Save();
                if (oStep.sErrorMessage != "")
                    WriteMessage(oStep.sErrorMessage, "Save"); 

            }
            oFileSequence.bIsDirty = false;
            Text = oFileSequence.GetProcessName();            
            Cursor.Current = Cursors.Default;
        }


        private void OnError(object s, EventArgs e)
        {
            //string sErr = (string)e; 
            //rtbErrors.Text += "-";
        }


        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem ts = (ToolStripMenuItem)sender;
            if (ts != null)
            {
                ContextMenuStrip cMenu = ts.Owner as ContextMenuStrip;

                if (cMenu != null)
                {
                    RichTextBox rtb = (RichTextBox)cMenu.SourceControl;
                    if (rtb != null)
                        rtb.SelectAll();
                }
            }
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem ts = (ToolStripMenuItem)sender;
            if (ts != null)
            {
                ContextMenuStrip cMenu = ts.Owner as ContextMenuStrip;

                if (cMenu != null)
                {
                    try
                    {
                        RichTextBox rtb = (RichTextBox)cMenu.SourceControl;
                        if (rtb != null)
                            if (rtb.SelectedText != "")
                                Clipboard.SetText(rtb.SelectedText);
                    }
                    catch (Exception oEx)
                    {
                    }
                }
            }
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            try
            {
                ToolStripMenuItem ts = (ToolStripMenuItem)sender;
                if (ts != null)
                {
                    ContextMenuStrip cMenu = ts.Owner as ContextMenuStrip;

                    if (cMenu != null)
                    {
                        Control  rtb = cMenu.SourceControl;
                        if (rtb != null)
                        {
                            if (rtb.GetType() == rtbErrors.GetType())
                                ((RichTextBox)rtb).Paste();
                            else if (rtb.GetType() == panel1.GetType())
                            {
                                string sSql = Clipboard.GetText();
                                if (sSql.Length > 33)
                                {
                                    if (sSql.Substring(0, 33) == "insert into T_API_QD_PROCESS_STEP")
                                    {
                                        string sNewId = GetNextStepId();
                                        sSql = sSql.Replace("$ProcessId$", tstbId.Text);
                                        sSql = sSql.Replace("$StepId$", sNewId);
                                        sSql = "Begin\r\n" + sSql.Replace("\n", "\r\n") + "End;\r\n";
                                        RunSql(sSql);
                                        RefreshScreen();
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception Ex) { }
        }

        string GetNextStepId()
        {
            string sRet = "0";
            foreach (CStep oStep in oFileSequence.oSteps)
                sRet = oStep.sId;
            return (Convert.ToInt32(sRet) + 1).ToString();
        }

        bool AddStepFromFile(string sFilename, int iX, int iY)
        {
            bool bRet = false;
            // Make sure the possition is valid 
            if (iX < 0) iX = 0; if (iY < 0) iY = 0;

            string sQD = "", sType = "-", sProcess = "", sMode = "", sStepId = GetNextStepId();
            List<string> arrInputs = new List<string>();

            XmlDocument oXmlDoc = new XmlDocument();
            try
            {
                string sXml = "";
                using (StreamReader sr = new StreamReader(sFilename))
                {
                    sXml = sr.ReadToEnd();
                    // Remove the <?xml version="1.0" encoding="UTF-8"?>
                    sXml = sXml.Replace("<?xml version=\"1.0\" encoding=\"UTF8\"?>", "");
                    sXml = sXml.Replace("xsi:nil=\"true\"", "");
                    int iStart = sXml.IndexOf("<Root>");
                    if (iStart > 0)
                    {
                        sXml = sXml.Substring(iStart);
                    }
                    
                }
                oXmlDoc.LoadXml(sXml);
                XmlNode oNodeMethod = oXmlDoc.SelectSingleNode("/Root/XMLHeader/MethodName/text()");
                if (oNodeMethod == null)
                {                    
                    WriteMessage("Incorrect xml file format (no value at /Root/XMLHeader/MethodName)", "AddStepFromFile"); 
                }
                else
                {
                    XmlNode oNode = null;
                    if (oNodeMethod.Value == "QueryDef")
                    {
                        oNode = oXmlDoc.SelectSingleNode("/Root/XMLBody/Queries/Query/@Name");
                        sQD = oNode.Value;
                        string[] sArr = sQD.Split('.');
                        sProcess = sArr[sArr.Count() - 1];
                        sType = "QueryDef";

                        //Make Sure the name is unique
                        foreach (CStep oStep in oFileSequence.oSteps)
                        {
                            if (oStep.sName == sProcess)
                                sProcess += "1";
                        }

                        //Now get all the inputs 
                        XmlNode oParms = oXmlDoc.SelectSingleNode("/Root/XMLBody/Queries/Query/Param");
                        if (oParms != null)
                        {
                            XmlNodeList xnList = oParms.ChildNodes;
                            foreach (XmlNode xn in xnList)
                            {
                                arrInputs.Add(xn.Name + "\t" + xn.InnerText);
                            }
                        }
                    }
                    else
                    {
                        oNode = oXmlDoc.SelectSingleNode("/Root/XMLBody/Updates/Update/@Name");
                        if (oNode != null)
                            sQD = oNode.Value;

                        oNode = oXmlDoc.SelectSingleNode("/Root/XMLBody/Updates/Update/@Mode");
                        if (oNode != null)
                            sMode = oNode.Value;


                        string[] sArr = sQD.Split('.');
                        sProcess = sArr[sArr.Count() - 1];
                        sType = "UpdateQueryDef";
                        //Make Sure the name is unique
                        foreach (CStep oStep in oFileSequence.oSteps)
                        {
                            if (oStep.sName == sProcess)
                                sProcess += "1";
                        }

                        //Now get all the inputs 
                        XmlNode oUpdate = oXmlDoc.SelectSingleNode("/Root/XMLBody/Updates/Update");
                        if (oUpdate != null)
                        {
                            XmlNodeList xnList = oUpdate.ChildNodes;
                            foreach (XmlNode xn in xnList)
                            {
                                if (xn.Attributes.Count > 1)
                                {
                                    string sQDName = xn.Attributes["Name"].Value;
                                    string sSubMode = xn.Attributes["Mode"].Value;
                                    string sName = xn.Name;
                                    XmlNodeList SubXnList = xn.ChildNodes;
                                    string sStepName = AddSubStep(iX,iY,sStepId,sName, sSubMode,sQDName, SubXnList);
                                    sStepId = (Convert.ToUInt32(sStepId) + 1).ToString();
                                    arrInputs.Add("@" + xn.Name + "\t" + sStepName + ">XmlBody");
                                }
                                else
                                {
                                    arrInputs.Add(xn.Name + "\t" + xn.InnerText);
                                }
                            }
                        }
                    }

                    if (oNode != null)
                    {

                        CStep oStep = new CStep(oFileSequence, GetConnection());
                        int i = 5;
                        foreach (string sInputs in arrInputs)
                        {
                            string[] arrInput = sInputs.Split('\t');
                            arrInput[0] = arrInput[0].Replace("'", "''");
                            arrInput[1] = arrInput[1].Replace("'", "''");
                            CInput oInput = new CInput(arrInput[0], arrInput[1], i.ToString(), oStep);
                            oStep.lInputs.Add(oInput);
                            i++;
                        }

                        oStep.sType = sType;
                        oStep.sMode = sMode; oStep.sId = sStepId;
                        oStep.sProcessId = sId;
                        oStep.SetDisplayValue("X", (15 + iX * 21).ToString()); oStep.SetDisplayValue("Y", (15 + iY * 12).ToString());
                        oStep.SetDisplayValue("Height", "110"); oStep.SetDisplayValue("Width", "200");
                        oStep.sName = sProcess; oStep.sQueryName = sQD;
                        oFileSequence.oSteps.Add(oStep);
                        AddControl(oStep);
                        bRet = true;
                    }
                }
            }
            catch (Exception ex)
            {                
                WriteMessage(ex.Message, "AddStepFromFile-Error"); 
            }
            return bRet;
        }

        private string  AddSubStep(int iX, int iY, string sStepId, string sName, string sMode,string sQdName, XmlNodeList oXnList)
        {
            CStep oStep = new CStep(oFileSequence, GetConnection());
            int i = 5;
            foreach (XmlNode oNode in oXnList)
            {
                CInput oInput = new CInput(oNode.Name, oNode.InnerText, i.ToString(), oStep);
                oStep.lInputs.Add(oInput);
                i++;
            }

            COutput oOut = new COutput("XmlBody", sName, i.ToString(), oStep);
            oStep.lOutputs.Add(oOut);

            string[] arrName = sName.Split('.');
            oStep.sType = "ChildUpdateQueryDef";
            oStep.sMode = sMode; oStep.sId = sStepId;
            oStep.sProcessId = sId;
            oStep.SetDisplayValue("X", (15 + (iX-1) * 21).ToString()); oStep.SetDisplayValue("Y", (15 + (iY-1) * 12).ToString());
            oStep.SetDisplayValue("Height", "110"); oStep.SetDisplayValue("Width", "200");
            oStep.sName = oFileSequence.UnqueName(arrName[arrName.Count() - 1]); 

            oStep.sQueryName = sQdName;
            oFileSequence.oSteps.Add(oStep);
            AddControl(oStep);

            return oStep.sName;
        }

        private void contextMenuStrip2_Opening(object sender, CancelEventArgs e)
        {
            string sType = sender.GetType().ToString();
        }

        private void runStepToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();

            if (oStep == null)
            {
                WriteMessage("Select a step", "runStepToolStripMenuItem_Click-01"); 
            }
            else
            {
                // Get all the inputs ( ? ) 
                List<string> arrInputs = new List<string>();
                
                WriteMessage("Started as " + DateTime.Now.ToString(), "runStepToolStripMenuItem_Click-02"); 
                foreach (CInput oIn in oStep.lInputs)
                {
                    if (oIn.sValue == "?")
                        arrInputs.Add(oStep.sName + "." + oIn.sName);
                }

                // If there are any inputs that need to be input by the user
                GetInputs(arrInputs);


                // Update all the fixed values 
                foreach (CInput oIn in oStep.lInputs)
                {
                    if ((oIn.sValue != "?") && (oIn.sValue.IndexOf('>') < 0) )
                        oIn.sCalValue = oIn.sValue;
                }


                if (oStep != null)
                {
                    string sFilename1 = oIni.IniReadValue("Settings", "TempFolder", "C:\\Sapiens\\Sequence\\Temp\\") + "" + oIni.IniReadValue("Settings", "RunNum", "0") + "-" + oStep.sProcessId + "-" + oStep.sId + "-In.xml";
                    string sFilename2 = oIni.IniReadValue("Settings", "TempFolder", "C:\\Sapiens\\Sequence\\Temp\\") + "" + oIni.IniReadValue("Settings", "RunNum", "0") + "-" + oStep.sProcessId + "-" + oStep.sId + "-Out.xml";

                    oStep.Calculate(sFilename1, sFilename2);
                    Control oCon = panel1.Controls[oStep.GetControlName()];
                    if (((usStep)oCon).ShowType == usStep.eShowType.Values)
                        ((usStep)oCon).ShowType = usStep.eShowType.Values;

                    if (oStep.sType == "IF")
                        WriteMessage("    If returned " + (oFileSequence.bIfElseFlag == false).ToString(), "runStepToolStripMenuItem_Click-03");
                        
                }

                foreach (COutput oOut in oStep.lOutputs)
                    WriteMessage("    " + oOut.sName + " : " + oOut.sCalValue, "runStepToolStripMenuItem_Click-04" + oOut.sID);


                WriteMessage("Finished as " + DateTime.Now.ToString(), "runStepToolStripMenuItem_Click-05");
                
            }
        }

        private void showResultsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();
            if (oStep == null)
            {                
                WriteMessage("Select a step", "showResultsToolStripMenuItem_Click");
            }
            else
            {
                Results oRes = new Results(oStep.sId.ToString(), oStep.sProcessId.ToString() );
                oRes.ShowDialog(this);
            }
        }

        private void panel1_DragEnter(object sender, DragEventArgs e)
        {
            
            if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
        }

        private void panel1_DragDrop(object sender, DragEventArgs e)
        {
            
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            Point oCurrent = Cursor.Position;
            foreach (string sFilename in files)
            {
                //Console.WriteLine(file);
                if (sFilename.Substring(sFilename.Length - 3, 3).ToLower() == "xml")
                {
                    int iX = ((oCurrent.X - 15) / 210), iY = (oCurrent.Y - 15) / 120;
                    AddStepFromFile(sFilename, iX, iY);
                    
                }
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();
            if (oStep == null)
            {                
                WriteMessage("Select a step", "deleteToolStripMenuItem_Click");
            }
            else
            {
                CheckToSave();
                Control[] oCon = panel1.Controls.Find(oStep.GetControlName(), false);
                if (oCon.Count() == 1)
                {
                    panel1.Controls.Remove(oCon[0]);
                    oFileSequence.oSteps.Remove(oStep);
                }

                string sSql = "Begin\r\ndelete from  t_api_qd_process_step where process_id=" + sId + " and id = " + oStep.sId + ";\r\n";
                sSql += "delete from  t_api_qd_process_step_params where process_id=" + sId + " and step_id = " + oStep.sId + ";\r\n";
                sSql += "delete from  t_api_qd_process_step where process_id=" + sId + " and id = " + oStep.sId + ";\r\n";
                sSql += "end;\r\n";
                RunSql(sSql);
                RefreshScreen();
            }
        }

        private void reorderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmReorder oFrmReorder = new FrmReorder(ref oFileSequence);
            oFrmReorder.ShowDialog(this);
            if (oFrmReorder.bToSave)
            {
                foreach (CStep oStep in oFileSequence.oSteps)
                {
                    usStep oToUpdate = ((usStep)panel1.Controls[oStep.GetControlName()]);
                    if (oToUpdate != null)
                    oToUpdate.UpdateId(oStep.sId);
                }
                string sSql = "Begin \r\n";
                sSql += "delete from T_API_QD_PROCESS_STEP where PROCESS_ID=" + tstbId.Text + ";\r\n";
                sSql += "delete from T_API_QD_PROCESS_STEP_PARAMS where PROCESS_ID=" + tstbId.Text + ";\r\n";
                sSql += "end;";
                RunSql(sSql);
                Save();
            }
        }

        private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowProperties();
        }

        /*private void WriteError(string sError)
        {
            rtbErrors.Text += sError + "\r\n";
        }*/

        private void historyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (GetWiki() == null)
                WriteMessage("Disconnected from Source control !!", "historyToolStripMenuItem_Click");
            else
            {
                //http://ukdt198.sapiens.int/mediawiki/index.php/MMSequence.LoadAccountStructureFromFileList
                IniFile oIni = new Ini.IniFile(sIniFilePath);
                string sWikiPath = oIni.IniReadValue("Wiki", "Path", "http://ukdt198.sapiens.int/mediawiki");
                string sWikiSite = oIni.IniReadValue("Wiki", "Library", "Sequence");

                sWikiPath += "/index.php/" + sWikiSite + "." + oFileSequence.sName;

                ProcessStartInfo startInfo = new ProcessStartInfo(sWikiPath);
                startInfo.WindowStyle = ProcessWindowStyle.Maximized;
                Process.Start(startInfo);

            }
        }

        private void checkInToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (GetWiki() == null)
                WriteMessage("Disconnected from Source control !!", "historyToolStripMenuItem_Click");
            else
            {
                Cursor.Current = Cursors.WaitCursor;                
                String sUser = oIni.IniReadValue("Wiki", "User", "Unknown");

                string sCode = GetSaveCommand();
                CWikiSourceControl oWiki = GetWiki();
                oWiki.CheckIn(tstbName.Text, tstbId.Text, sCode, sUser);
                UpdateIcon();
                Cursor.Current = Cursors.Default;
            }
        }

        private string GetUserName()
        {
            return oIni.IniReadValue("Wiki", "User", "");
        }

        private void checkOutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            if (GetWiki() == null)
                WriteMessage("Disconnected from Source control !!", "historyToolStripMenuItem_Click");
            else
            {
                CWikiSourceControl oWikiSourceControl = GetWiki();
                // If checked out                     
                if (eSCState == eSourceControlState.CheckedIn)
                {
                    string sMaster = oWikiSourceControl.GetText(tstbName.Text);
                    string sCode = GetSaveCommand();
                    sCode = sCode.Replace("\r\n", ""); sCode = sCode.Replace("\r", ""); sCode = sCode.Replace("\n", "");
                    string sMasterToCompare = sMaster.Replace("\r\n", ""); sMasterToCompare = sMasterToCompare.Replace("\r", ""); sMasterToCompare = sMasterToCompare.Replace("\n", "");
                    if (sMasterToCompare.CompareTo(sCode) == 0)
                    {
                        oWikiSourceControl.CheckOut(tstbId.Text, tstbName.Text, GetUserName());
                        UpdateIcon();
                    }
                    else
                    {
                        UpdateIcon();
                        DialogResult dialogResult = MessageBox.Show("Your version is different to the master version\r\nDo you want to update your version with the master", "Source control", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                        if (dialogResult == DialogResult.Yes)
                        {
                            string sSql = "Begin\r\n" + sMaster.Replace("\n", "\r\n") + "End;\r\n";
                            RunSql(sSql);
                            oWikiSourceControl.CheckOut(tstbId.Text, tstbName.Text, GetUserName());
                            UpdateIcon();
                            RefreshScreen();
                        }
                        else if (dialogResult == DialogResult.No)
                        {
                            oWikiSourceControl.CheckOut(tstbId.Text, tstbName.Text, GetUserName());
                            UpdateIcon();
                        }
                    }
                }
                else if (eSCState == eSourceControlState.CheckedOutByMe)
                {
                    WriteMessage("Already checked out by you (" + GetUserName() + ")", "checkOutToolStripMenuItem_Click-03");
                }
                else if (eSCState == eSourceControlState.CheckedOutNotByMe)
                {
                    CWikiSourceControl.CSCStatus oCSCStatus = oWikiSourceControl.FindById(tstbId.Text);
                    WriteMessage("Checked out by " + oCSCStatus.sCheckedOutTo + " at " + oCSCStatus.sTimeDate, "checkOutToolStripMenuItem_Click-04");
                }
            }
            Cursor.Current = Cursors.Default;
        }

        private void sourceControlToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void importToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Service call Files (XML files *In.xml)|*In.xml|All Files (*.*)|*.*";
            if (openFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                AddStepFromFile(openFileDialog.FileName, 10, 10);
                //RefreshScreen();
            }
        }

        private void SaveFile(string sFrom, string sTo)
        {
            //File.Copy(sFrom, sTo);
        }

        private void showXMLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();            
            Results oRes = new Results("", oStep.CreateInput(), "");
            oRes.ShowDialog(this);
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            string sType = sender.GetType().ToString();
            m_oConContextMenuStripSourceControl = ((ContextMenuStrip)sender).SourceControl;

        }

        private void runSequenceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RunSequence();
        }

        private void sequenceResultsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();
            Results oRes = new Results(oStep.sId,oStep.sProcessId);
            oRes.ShowDialog(this);
        }

        private void newStepToolStripMenuItem_Click(object sender, EventArgs e)
        {
           
        }

        private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void compareToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (GetWiki() == null)
                WriteMessage("Disconnected from Source control !!", "historyToolStripMenuItem_Click");
            else
            {
                string sMaster = GetWiki().GetText(tstbName.Text);
                string sCode = GetSaveCommand();
                sCode = sCode.Replace("\r\n", "\n");

                using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Temp\Master.sql", false))
                    file.Write(sMaster);

                using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Temp\Local.sql", false))
                    file.Write(sCode + "\n");

                ProcessStartInfo startInfo = new ProcessStartInfo("Winmerge.exe");
                startInfo.WindowStyle = ProcessWindowStyle.Maximized;
                startInfo.Arguments = "C:\\Temp\\Master.sql C:\\Temp\\Local.sql";
                Process.Start(startInfo);
            }
        }

        private void updateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (GetWiki() == null)
                WriteMessage("Disconnected from Source control !!", "historyToolStripMenuItem_Click");
            else
            {
                Cursor.Current = Cursors.WaitCursor;
                string sMaster = GetWiki().GetText(tstbName.Text);
                string sMasterToCompare = sMaster.Replace("\r\n", ""); sMasterToCompare = sMasterToCompare.Replace("\r", ""); sMasterToCompare = sMasterToCompare.Replace("\n", "");
                string sCode = GetSaveCommand();
                sCode = sCode.Replace("\r\n", ""); sCode = sCode.Replace("\r", ""); sCode = sCode.Replace("\n", "");


                if (sMasterToCompare.CompareTo(sCode) != 0)
                {
                               
                    DialogResult dialogResult = MessageBox.Show("Your version is different to the master version\r\nDo you want to update your version with the master", "Source control", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (dialogResult == DialogResult.Yes)
                    {
                        string sSql = "Begin\r\n" + sMaster.Replace("\n", "\r\n") + "End;\r\n";
                        RunSql(sSql);
                        RefreshScreen();
                    }
                }
                Cursor.Current = Cursors.Default;
            }
        }

        private void exportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog oFolderBrowserDialog = new FolderBrowserDialog();
            oFolderBrowserDialog.ShowDialog(this);
            if (oFolderBrowserDialog.SelectedPath.Length > 0)
            {

                string sCode = GetSaveCommand();
                using (System.IO.StreamWriter file = new System.IO.StreamWriter(oFolderBrowserDialog.SelectedPath + "\\" + tstbName.Text + ".sql", false))
                    file.Write(sCode);
            }
        }

        private string GetNextId()
        {
            string sRet = "-1";
            String sSql = @"
select max(ID) 
from t_api_qd_process 
";
            sSql = CSqlString.TestType(sSql, GetConnectionType());
            try
            {
                DbCommand command = GetConnection().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;
                DbDataReader oDataReader = command.ExecuteReader();

                if (oDataReader.Read())
                {
                    sRet = (Convert.ToInt32(oDataReader[0].ToString()) + 1).ToString();
                }
                oDataReader.Close();
            }
            catch (Exception ex)
            {
                WriteMessage(ex.ToString(), "GetNextId");
            }
            return sRet;
        }

        private string GetStepNextId(string sProcessId)
        {
            string sRet = "-1";
            String sSql = @"
select max(ID) 
from T_API_QD_PROCESS_STEP where PROCESS_ID=$PROCESS_ID$
";
            sSql = sSql.Replace("$PROCESS_ID$", sProcessId);
            sSql = CSqlString.TestType(sSql, GetConnectionType());
            try
            {
                DbCommand command = GetConnection().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;
                DbDataReader oDataReader = command.ExecuteReader();

                if (oDataReader.Read())
                {
                    sRet = (Convert.ToInt32(oDataReader[0].ToString()) + 1).ToString();
                }
                oDataReader.Close();
            }
            catch (Exception ex)
            {
                WriteMessage(ex.ToString(), "GetStepNextId");
            }
            return sRet;
        }

        
        private void cloneToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sCode = GetSaveCommand();
            string sNewId = GetNextId();
            sCode = sCode.Replace("(" + sId, "(" + sNewId);
            sCode = sCode.Replace("ID=" + sId, "ID=" + sNewId);
            sCode = sCode.Replace(tstbName.Text, tstbName.Text + "Clone");
            sCode = "Begin\r\n" + sCode.Replace("\n", "\r\n") + "End;\r\n";
            RunSql(sCode);
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();
            if (oStep == null)
            {
                WriteMessage("Select a step", "copyToolStripMenuItem_Click");
            }
            else
            {
                Clipboard.Clear();
                Clipboard.SetText( oStep.ToCopySql());
            }
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string sSql = Clipboard.GetText();
            if (sSql.Length > 33)
            {
                if (sSql.Substring(0, 33) == "insert into T_API_QD_PROCESS_STEP")
                {
                    string sNewId = GetNextStepId();
                    sSql = sSql.Replace("$ProcessId$", tstbId.Text);
                    sSql = sSql.Replace("$StepId$", sNewId);
                    sSql = "Begin\r\n" + sSql.Replace("\n", "\r\n") + "End;\r\n";
                    RunSql(sSql);
                    RefreshScreen();
                }
            }
        }

        private void toolStripButton5_Click_1(object sender, EventArgs e)
        {
            long iRunNum = Convert.ToInt64(oIni.IniReadValue("Settings", "RunNum", "0"));
            string sFolder = oIni.IniReadValue("Settings", "LogFolder", "C:\\Sapiens\\Sequence\\Logs\\");
            string sFilename = sFolder + "Run-" + iRunNum.ToString() + ".html"; 


            ProcessStartInfo startInfo = new ProcessStartInfo(sFilename);
            startInfo.WindowStyle = ProcessWindowStyle.Maximized;
            try{
            Process.Start(startInfo);
            }
            catch ( Exception Ex) 
            {

            }
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            if (toolStripButton7.ToolTipText == "Show Lines")
            {
                toolStripButton7.ToolTipText = "Hide Lines";
                m_bShowLines = true;
            }
            else
            {
                toolStripButton7.ToolTipText = "Show Lines";
                m_bShowLines = false;
            }
            CheckToSave();
            Cursor.Current = Cursors.WaitCursor;
            RefreshScreen();
            Cursor.Current = Cursors.Default;
        }

        private void allDownToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (CStep oSt in oFileSequence.oSteps)
            {
                
                ((usStep)panel1.Controls[oSt.GetControlName()]).Top += 120;
                oSt.SetDisplayValue("Y", ((usStep)panel1.Controls[oSt.GetControlName()]).Top.ToString());
            }
        }

        private string MakeUniqueNewName()
        {
            //Make Sure the name is unique
            string sName = "New";
            int iLoop = 1;
            CStep oStep = oFileSequence.oSteps.Find(element => element.sName == sName);
            while (oStep != null)
            {
                sName = "New" + iLoop.ToString();
                oStep = oFileSequence.oSteps.Find(element => element.sName == sName);
                iLoop++;
            }
            return sName;
        }

        private void qDStepToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "QueryDef");
        }

        private void ifStepToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "IF");
            NewStep(iTop, iLeft + 300, MakeUniqueNewName(), "END IF");

        }

        private void whileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "FOR");
            NewStep(iTop, iLeft + 300, MakeUniqueNewName(), "END FOR");
        }

        private void queryDefUpdateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "QueryDefUpdate");
        }

        private void queryDefProcessToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "QueryDefProcess");
        }

        private void calculationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "Calculation");
        }

        private void constantToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "Constants");
        }

        private void textCommentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "TextComment");
        }

        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void inputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "Input");
        }

        private void outputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "Output");
        }

        string GetProcessId(string sQueryName)
        {
            string sRet = "";
            string sSql = @"
select ID from T_API_QD_PROCESS 
where name = '$sQueryName$'";
            sSql = sSql.Replace("$sQueryName$",sQueryName);
            
            try
            {
                DbCommand command = GetConnection().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;
                DbDataReader oDataReader = command.ExecuteReader();

                if (oDataReader.Read())
                {
                    sRet = oDataReader[0].ToString();
                }
                oDataReader.Close();
            }
            catch (Exception ex)
            {
                WriteMessage(ex.ToString(), "GetProcessId");
            }
            return sRet;
        }

        private void openProcessToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CStep oStep = FindFocusStep();

            if (oStep == null)
            {
                WriteMessage("Select a step", "openProcessToolStripMenuItem_Click");
            }
            else
            {
                if (oStep.sType == "QueryDefProcess")
                {
                    string sId = GetProcessId(oStep.sQueryName);
                    Program.mf.OpenProcess(sId);
                }
            }
        }

        private void FrmSequence2_FormClosing(object sender, FormClosingEventArgs e)
        {
            WriteMessage("Auto backup", "");
            string sCode = GetSaveCommand();
            sCode = sCode.Replace("\r\n", "\n");

            string sTempFolder = oIni.IniReadValue("Settings", "AutoBackupFolder");

            using (System.IO.StreamWriter file = new System.IO.StreamWriter(sTempFolder + "AutoBackup" + sId + ".sql", false))
                file.Write(sCode + "\n");

        }

        private void fORLISTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "FOR LIST");
            NewStep(iTop, iLeft + 300, MakeUniqueNewName(), "END FOR LIST");

        }

        private void mapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int iTop = contextMenuStrip2.Top;
            int iLeft = contextMenuStrip2.Left;

            NewStep(iTop, iLeft, MakeUniqueNewName(), "Map");
        }
    }
}
